package la.bbs558.util;

import ch.qos.logback.core.util.CloseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import fr.opensagres.poi.xwpf.converter.core.FileImageExtractor;
import fr.opensagres.poi.xwpf.converter.core.FileURIResolver;
import fr.opensagres.poi.xwpf.converter.core.XWPFConverterException;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import la.bbs558.entity.enums.OssFolder;
import la.bbs558.exception.MsgException;
import la.bbs558.entity.params.SendPostForAdminParams;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
@Slf4j
public class WordUtil {
    @Resource
    private OssUtil ossUtil;

    public String covert2RichText(SendPostForAdminParams params) {
        MultipartFile file = params.getFile();
        File destFile = null;
        try {
            destFile = fileDownloadToLocalPath(file);
            //解析word
            String content = dealWithCaseInfoRichText(destFile);
            //解析word中的图片
            return dealWithCaseInfoRichTextToPictureChild(content, params);
        } finally {
            FileUtil.deleteFile(destFile);
        }
    }

    @SneakyThrows
    private String dealWithCaseInfoRichText(File destFile) {
        if (!destFile.exists()) {
            throw new MsgException("临时文件创建失败,请重新上传！");
        }
        // 判断是否为docx文件
        if (!destFile.getName().endsWith(".docx") && !destFile.getName().endsWith(".DOCX")) {
            throw new MsgException("上传失败,请重新上传！");
        }
        // 1)加载word文档生成XWPFDocument对象
        try (FileInputStream in = new FileInputStream(destFile); XWPFDocument document = new XWPFDocument(in)) {
            // 2)解析XHTML配置（这里设置IURIResolver来设置图片存放的目录）
            File imageFolderFile = new File(String.valueOf(destFile.getParentFile()));
            XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(imageFolderFile));
            options.setExtractor(new FileImageExtractor(imageFolderFile));
            options.setIgnoreStylesIfUnused(false);
            options.setFragment(true);
            // 使用字符数组流获取解析的内容
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            XHTMLConverter.getInstance().convert(document, baos, options);
            // 带样式的内容(富文本)
            return removeStyleFromHtml(baos.toString());
        } catch (IOException | XWPFConverterException e) {
            log.error("解析word文件失败", e);
        }
        throw new MsgException("解析word文件失败,请重新上传！");
    }

    private String removeStyleFromHtml(String html) {
        // 匹配style属性的正则表达式
        String regexStyle = "style\\s*=\\s*\"[^\"]*\"";
        Matcher matcher = Pattern.compile(regexStyle).matcher(html);
        html = matcher.replaceAll("");
        String regexClass = "class\\s*=\\s*\"[^\"]*\"";
        // 去掉所有匹配的style属性
        return Pattern.compile(regexClass).matcher(html).replaceAll("");
    }


    private String dealWithCaseInfoRichTextToPictureChild(String content, SendPostForAdminParams params) {
        List<String> imagesFiles = HtmlUtil.regexMatchPicture(content);
        if (Objs.isNotEmpty(imagesFiles)) {
            JSONArray jsonArray = new JSONArray();
            for (String imagesFile : imagesFiles) {
                File file = new File(imagesFile);
                FileInputStream inputStream = null;
                try {
                    inputStream = new FileInputStream(file);
                    String link = ossUtil.uploadFile(inputStream, OssFolder.BBS, file.getName());
                    content = content.replace(imagesFile, ossUtil.getFullUrl(link));
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("url", link);
                    jsonObject.put("type", "image");
                    jsonArray.add(jsonObject);
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                } finally {
                    CloseUtil.closeQuietly(inputStream);
                }
            }
            params.setMediaJson(jsonArray.toJSONString());
        }
        return content;
    }

    /**
     * 下载到本地路径
     */
    private File fileDownloadToLocalPath(MultipartFile file) {
        File destFile = null;
        try {
            String suffix = FileUtil.getSuffix(file.getOriginalFilename());
            destFile = FileUtil.createTempFile("." + suffix, true);
            if (!destFile.getParentFile().exists()) {
                boolean mkdirs = destFile.getParentFile().mkdirs();
                if (!mkdirs) {
                    throw new MsgException("创建临时文件目录失败");
                }
            }
            file.transferTo(destFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return destFile;
    }


}
